home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / asm-mn10300 / div64.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  2.7 KB  |  101 lines

  1. /* MN10300 64-bit division
  2.  *
  3.  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  4.  * Written by David Howells (dhowells@redhat.com)
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public Licence
  8.  * as published by the Free Software Foundation; either version
  9.  * 2 of the Licence, or (at your option) any later version.
  10.  */
  11. #ifndef _ASM_DIV64
  12. #define _ASM_DIV64
  13.  
  14. #include <linux/types.h>
  15.  
  16. extern void ____unhandled_size_in_do_div___(void);
  17.  
  18. /*
  19.  * divide n by base, leaving the result in n and returning the remainder
  20.  * - we can do this quite efficiently on the MN10300 by cascading the divides
  21.  *   through the MDR register
  22.  */
  23. #define do_div(n, base)                            \
  24. ({                                    \
  25.     unsigned __rem = 0;                        \
  26.     if (sizeof(n) <= 4) {                        \
  27.         asm("mov    %1,mdr    \n"                \
  28.             "divu    %2,%0    \n"                \
  29.             "mov    mdr,%1    \n"                \
  30.             : "+r"(n), "=d"(__rem)                \
  31.             : "r"(base), "1"(__rem)                \
  32.             : "cc"                        \
  33.             );                            \
  34.     } else if (sizeof(n) <= 8) {                    \
  35.         union {                            \
  36.             unsigned long long l;                \
  37.             u32 w[2];                    \
  38.         } __quot;                        \
  39.         __quot.l = n;                        \
  40.         asm("mov    %0,mdr    \n"    /* MDR = 0 */        \
  41.             "divu    %3,%1    \n"                \
  42.             /* __quot.MSL = __div.MSL / base, */        \
  43.             /* MDR = MDR:__div.MSL % base */            \
  44.             "divu    %3,%2    \n"                \
  45.             /* __quot.LSL = MDR:__div.LSL / base, */        \
  46.             /* MDR = MDR:__div.LSL % base */            \
  47.             "mov    mdr,%0    \n"                \
  48.             : "=d"(__rem), "=r"(__quot.w[1]), "=r"(__quot.w[0])    \
  49.             : "r"(base), "0"(__rem), "1"(__quot.w[1]),        \
  50.               "2"(__quot.w[0])                    \
  51.             : "cc"                        \
  52.             );                            \
  53.         n = __quot.l;                        \
  54.     } else {                            \
  55.         ____unhandled_size_in_do_div___();            \
  56.     }                                \
  57.     __rem;                                \
  58. })
  59.  
  60. /*
  61.  * do an unsigned 32-bit multiply and divide with intermediate 64-bit product
  62.  * so as not to lose accuracy
  63.  * - we use the MDR register to hold the MSW of the product
  64.  */
  65. static inline __attribute__((const))
  66. unsigned __muldiv64u(unsigned val, unsigned mult, unsigned div)
  67. {
  68.     unsigned result;
  69.  
  70.     asm("mulu    %2,%0    \n"    /* MDR:val = val*mult */
  71.         "divu    %3,%0    \n"    /* val = MDR:val/div;
  72.                      * MDR = MDR:val%div */
  73.         : "=r"(result)
  74.         : "0"(val), "ir"(mult), "r"(div)
  75.         );
  76.  
  77.     return result;
  78. }
  79.  
  80. /*
  81.  * do a signed 32-bit multiply and divide with intermediate 64-bit product so
  82.  * as not to lose accuracy
  83.  * - we use the MDR register to hold the MSW of the product
  84.  */
  85. static inline __attribute__((const))
  86. signed __muldiv64s(signed val, signed mult, signed div)
  87. {
  88.     signed result;
  89.  
  90.     asm("mul    %2,%0    \n"    /* MDR:val = val*mult */
  91.         "div    %3,%0    \n"    /* val = MDR:val/div;
  92.                      * MDR = MDR:val%div */
  93.         : "=r"(result)
  94.         : "0"(val), "ir"(mult), "r"(div)
  95.         );
  96.  
  97.     return result;
  98. }
  99.  
  100. #endif /* _ASM_DIV64 */
  101.